package net.towee.client.com.lobby.presenter;

import java.util.Arrays;
import java.util.List;

import net.towee.client.ToweeGinjector;
import net.towee.client.com.app.AppController.Component;
import net.towee.client.com.lobby.Lobby;
import net.towee.client.event.core.ShowComponentEvent;

import com.google.gwt.core.client.GWT;
import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.event.dom.client.ClickHandler;
import com.google.gwt.event.dom.client.HasClickHandlers;
import com.google.gwt.event.shared.HandlerManager;
import com.google.gwt.user.client.ui.HasWidgets;
import com.google.gwt.user.client.ui.IsWidget;
import com.google.inject.Inject;

public class LobbyPresenter implements Lobby, ClickHandler {

	public interface Display extends IsWidget {
		/*
		 * Buttons for switching between steps
		 */
		HasClickHandlers getNicknameChanger();

		HasClickHandlers getProfileChanger();

		HasClickHandlers getGroupsChanger();

		HasClickHandlers getContactsChanger();

		HasClickHandlers getHelpChanger();

		HasWidgets getContainerForNextStep(Step step);

		/**
		 * Show given step
		 * 
		 * @param stepType
		 */
		void selectStep(Step stepType);
	}

	// Injected
	private final Display display;
	private final HandlerManager eventBus;
	private final ToweeGinjector injector;

	// List of steps
	private final List<Step> steps = Arrays.asList(Step.NICKNAME, Step.PROFILE, Step.GROUPS, Step.CONTACTS, Step.HELP);

	// Current showed step index in steps list
	private int currentStep = -1;
	private int loadedSteps = 0;

	@Inject
	public LobbyPresenter(Display display, HandlerManager eventBus, ToweeGinjector injector) {
		this.display = display;
		this.eventBus = eventBus;
		this.injector = injector;

		// Handle changing between steps
		display.getContactsChanger().addClickHandler(this);
		display.getProfileChanger().addClickHandler(this);
		display.getNicknameChanger().addClickHandler(this);
		display.getHelpChanger().addClickHandler(this);
		display.getGroupsChanger().addClickHandler(this);
	}

	@Override
	public void go(HasWidgets container) {
		// Show first step
		currentStep = -1;
		showNextStep();

		// Add to container
		container.clear();
		container.add(display.asWidget());
	}

	@Override
	public void onClick(ClickEvent event) {
		Object source = event.getSource();
		Step neededStep = null;

		if (source.equals(display.getContactsChanger()))
			neededStep = Step.CONTACTS;
		else if (source.equals(display.getGroupsChanger()))
			neededStep = Step.GROUPS;
		else if (source.equals(display.getHelpChanger()))
			neededStep = Step.HELP;
		else if (source.equals(display.getNicknameChanger()))
			neededStep = Step.NICKNAME;
		else if (source.equals(display.getProfileChanger()))
			neededStep = Step.PROFILE;

		if (neededStep != null)
			if (steps.indexOf(neededStep) >= loadedSteps)
				showNextStep();
			else if(validateCurrentStep())
				display.selectStep(neededStep);
	}
	
	/**
	 * Validate current step data and return result
	 * @return
	 */
	private boolean validateCurrentStep() {
		GWT.log("validate step "+currentStep);
		
		switch(steps.get(currentStep)){
		case NICKNAME: return injector.getLobbyNicknameStep().validateStep();
		case PROFILE: return injector.getLobbyProfileStep().validateStep();
		case GROUPS: return injector.getLobbyGroupsStep().validateStep();
		case CONTACTS: return injector.getLobbyPeopleStep().validateStep();
		case HELP: return injector.getLobbyHelpStep().validateStep();
		}
		
		return false;
	}

	@Override
	public void showNextStep() {
		// If next step not exists
		if (currentStep + 1 > steps.size() - 1)
			return;
		
		// If validation fail
		if (currentStep >= 0 && !validateCurrentStep())
			return;

		// Plus current step
		currentStep++;

		// If needed step not loaded
		if (currentStep >= loadedSteps) {
			// Plus one loaded step
			loadedSteps++;

			// Create needed step
			switch (steps.get(currentStep)) {
			case NICKNAME:
				injector.getLobbyNicknameStep().go(display.getContainerForNextStep(Step.NICKNAME));
				break;
			case PROFILE:
				injector.getLobbyProfileStep().go(display.getContainerForNextStep(Step.PROFILE));
				break;
			case GROUPS:
				injector.getLobbyGroupsStep().go(display.getContainerForNextStep(Step.GROUPS));
				break;
			case CONTACTS:
				injector.getLobbyPeopleStep().go(display.getContainerForNextStep(Step.CONTACTS));
				break;
			case HELP:
				injector.getLobbyHelpStep().go(display.getContainerForNextStep(Step.HELP));
				break;
			}
		}

		// Select step
		display.selectStep(steps.get(currentStep));

	}

	@Override
	public void closeLobby() {
		eventBus.fireEvent(new ShowComponentEvent(Component.DASHBOARD));
	}

}
